home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UWindow.cp < prev   
Encoding:
Text File  |  1991-05-01  |  57.9 KB  |  1,989 lines  |  [TEXT/MPS ]

  1. // UWindow.cp 
  2. // Copyright © 1987-1991 by Apple Computer Inc.    All rights reserved.
  3.  
  4. #ifndef __UWINDOW__
  5. #include <UWindow.h>
  6. #endif
  7.  
  8. #ifndef __UGEOMETRY__
  9. #include <UGeometry.h>
  10. #endif
  11.  
  12. #ifndef __ULIST__
  13. #include <UList.h>
  14. #endif
  15.  
  16. #ifndef __UADORNERS__
  17. #include <UAdorners.h>
  18. #endif
  19.  
  20. #ifndef __EDITIONS__
  21. #include <Editions.h>
  22. #endif
  23.  
  24. #ifndef __DIALOGS__
  25. #include <Dialogs.h>
  26. #endif
  27.  
  28. #ifndef __UAPPLICATION__
  29. #include <UApplication.h>
  30. #endif
  31.  
  32. #ifndef __UDOCUMENT__
  33. #include <UDocument.h>
  34. #endif
  35.  
  36. #ifndef __UPRINTHANDLER__
  37. #include <UPrintHandler.h>
  38. #endif
  39.  
  40. #ifndef __OSUTILS__
  41. #include <OSUtils.h>
  42. #endif
  43.  
  44. #ifndef __UMACAPPUTILITIES__
  45. #include <UMacAppUtilities.h>
  46. #endif
  47.  
  48. #ifndef __UFAILURE__
  49. #include <UFailure.h>
  50. #endif
  51.  
  52. #ifndef __UPATCH__
  53. #include <UPatch.h>
  54. #endif
  55.  
  56. #ifndef __UMACAPPGLOBALS__
  57. #include <UMacAppGlobals.h>
  58. #endif
  59.  
  60. #ifndef __ERRORS__
  61. #include <Errors.h>
  62. #endif
  63.  
  64. #ifndef __SYSEQU__
  65. #include <SysEqu.h>
  66. #endif
  67.  
  68. #ifndef __TRAPS__
  69. #include <Traps.h>
  70. #endif
  71.  
  72. #ifndef __DEVICES__
  73. #include <Devices.h>
  74. #endif
  75.  
  76. #ifndef __ULOMEM__
  77. #include <ULoMem.h>
  78. #endif
  79.  
  80. #ifndef __MENUS__
  81. #include <Menus.h>
  82. #endif
  83.  
  84. #ifndef __UMENUMGR__
  85. #include <UMenuMgr.h>
  86. #endif
  87.  
  88. #ifndef __FIXMATH__
  89. #include <FixMath.h>
  90. #endif
  91.  
  92. #ifndef __TOOLUTILS__
  93. #include <ToolUtils.h>
  94. #endif
  95.  
  96. #ifndef __RESOURCES__
  97. #include <Resources.h>
  98. #endif
  99.  
  100. //--------------------------------------------------------------------------------------------------
  101. Rect gStdWMoveBounds;
  102. Rect gStdWSizeRect;
  103. Rect gStdWScreenRect;
  104.  
  105. short gStdStaggerCount = 0;
  106.  
  107. //--------------------------------------------------------------------------------------------------
  108. #pragma segment MAClose
  109.  
  110. pascal void TCloseWindowCommand::DoIt(void)
  111. {
  112.     if (fView)
  113.         ((TWindow *)fView)->CloseByUser();
  114. }
  115.  
  116. //--------------------------------------------------------------------------------------------------
  117. #pragma segment MASelCommand
  118.  
  119. pascal void TCloseWindowCommand::ICloseWindowCommand(CmdNumber itsCmdNumber,
  120.                                                      TWindow* itsWindow)
  121. {
  122.     this->INoChangesCommand(itsCmdNumber, NULL, itsWindow);
  123. }
  124.  
  125. //--------------------------------------------------------------------------------------------------
  126. #pragma segment MAFields
  127.  
  128. pascal void TCloseWindowCommand::Fields(TObject* obj)// override 
  129. {
  130.     obj->DoToField("TCloseWindowCommand", NULL, bClass);
  131.  
  132.     inherited::Fields(obj);
  133. }
  134.  
  135. //--------------------------------------------------------------------------------------------------
  136. #pragma segment MAOpen
  137.  
  138. pascal void TWindow::Initialize(void)            // override 
  139. {
  140.     inherited::Initialize();
  141.  
  142.     fAdapted = FALSE;                            // Set by AdaptToScreen 
  143.     fClosesDocument = TRUE;
  144.     fConstTitle = 0;                            //!!! constant?
  145.     fContDifference = gZeroPt;
  146.     fContRgnInset = gZeroPt;
  147.     fDismissed = FALSE;
  148.     fDisposeOnFree = TRUE;
  149.     fDoFirstClick = FALSE;
  150.     fFloats = FALSE;
  151.     fForcedOnScreen = FALSE;                    // Set by ForceOnScreen 
  152.     fFreeOnClosing = FALSE;
  153.     fHideOnSuspend = FALSE;
  154.     fHorzCentered = FALSE;                        // Set by Center 
  155.     fIsActive = FALSE;
  156.     fIsClosable = TRUE;
  157.     fIsModal = FALSE;
  158.     fIsResizable = TRUE;
  159.     fMoveBounds = gStdWMoveBounds;
  160.  
  161.     // We can't tell if any changing will be required so we just set these false here.
  162.     // If the developer sets them true then we respect them or if the developer calls the
  163.     //corresponding functions we set them.
  164.     fMustAdapt = FALSE;
  165.     fMustForceOnScreen = FALSE;
  166.     fMustHorzCenter = FALSE;
  167.     fMustStagger = FALSE;
  168.     fMustVertCenter = FALSE;
  169.     fOpenInitially = TRUE;
  170.     fPreDocname = 0;                            //!!! contstant? 
  171.     fProcID = 0;                                //!!! contstant? 
  172.     fResizeLimits = gStdWSizeRect;
  173.     fStaggered = FALSE;                            // Set by SimpleStagger 
  174.     fTarget = this;
  175.     fTargetID = fIdentifier;
  176.     fUpdating = FALSE;
  177.     fVertCentered = FALSE;                        // Set by Center 
  178.     fWasHiddenOnSuspend = FALSE;
  179.     fWMgrWindow = NULL;
  180.     fGenerateActivates = TRUE;
  181. }
  182.  
  183. //--------------------------------------------------------------------------------------------------
  184. #pragma segment MAOpen
  185.  
  186. pascal void TWindow::IWindow(TDocument* itsDocument,
  187.                              WindowPtr itsWMgrWindow,
  188.                              Boolean canResize,
  189.                              Boolean canClose,
  190.                              Boolean disposeOnFree)
  191. {
  192.     short preDocname;
  193.     short constTitle;
  194.     Str255 aString;
  195.     FailInfo fi;
  196.     Point itsLocation;
  197.     VPoint itsSize;
  198.  
  199.     VOLATILE(itsWMgrWindow);
  200.     VOLATILE(disposeOnFree);
  201.     
  202.     if (fi.Try())
  203.     {
  204.  
  205.         SetPort(itsWMgrWindow);                    // So LocalToGlobal works 
  206.         Rect & thePortRect = itsWMgrWindow->portRect;//         WITH itsWMgrWindow->portRect)
  207.         {
  208.             itsLocation = thePortRect[topLeft];
  209.             LocalToGlobal(itsLocation);
  210.  
  211.             itsSize = VPoint(thePortRect.Length(vSel), thePortRect.Length(hSel));
  212.         }
  213.  
  214.         this->IView(itsDocument, NULL, itsLocation, itsSize, sizeVariable, sizeVariable);
  215.  
  216.         /* Initialize instance variables -- NOTE that we do this AFTER the call to IView (which
  217.           eventually triggers a call to Initialize in which intance variables are initialized) */
  218.         fWMgrWindow = itsWMgrWindow;
  219.         itsWMgrWindow = NULL;                    // so our failure handler works 
  220.         fDisposeOnFree = disposeOnFree;
  221.  
  222.         fProcID = GetWindowVariant(fWMgrWindow);
  223.         SetWRefCon(fWMgrWindow, ((long)this));
  224.  
  225.         fIsResizable = canResize;
  226.         if (canResize)
  227.             this->AddAdorner(gResizeIconAdorner, kLowestAdornPriority, FALSE);
  228.         fIsClosable = canClose;
  229.         this->BuildWindowRgns(this->BuildWindowRgns(kBuild));// sets fContRgnInset && fContDifference 
  230.  
  231.         this->SetResizeLimits(gStdWSizeRect[topLeft], gStdWSizeRect[botRight]);
  232.         this->GetTitle(aString);
  233.         if (ParseTitleTemplate(aString, preDocname, constTitle))
  234.             SetWTitle(fWMgrWindow, aString);
  235.         fPreDocname = preDocname;
  236.         fConstTitle = constTitle;
  237.  
  238.         this->InstallDocument(itsDocument);
  239.  
  240.         this->AddAdorner(gEraseAdorner, kHighestAdornPriority, FALSE);
  241.  
  242.         fi.Success();
  243.     }
  244.     else                                        // Recover
  245.         {
  246.             if (itsWMgrWindow)
  247.                 itsWMgrWindow = FreeIfWMgrWindow(itsWMgrWindow, disposeOnFree);
  248.  
  249.             this->Free();
  250.             fi.ReSignal();
  251.         }
  252. }
  253.  
  254. //--------------------------------------------------------------------------------------------------
  255. #pragma segment MAOpen
  256.  
  257. pascal void TWindow::IRes(TDocument* itsDocument,
  258.                           TView* itsSuperView,
  259.                           Ptr& itsParams)
  260. {
  261.     WindowPtr aWMgrWindow;
  262.     short preDocname;
  263.     short constTitle;
  264.     Str255 aString;
  265.     FailInfo fi;
  266.     WindowPtr behind;
  267.  
  268.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  269.  
  270.     VRect bounds(fLocation, fLocation + fSize);
  271.  
  272.     WindowTemplate & templateData = *((WindowTemplatePtr)itsParams);// WITH 
  273.     {
  274.         if (fi.Try())
  275.         {
  276.  
  277.             fProcID = templateData.procID;
  278.  
  279.             if (templateData.isModal)
  280.                 behind = (WindowPtr) - 1;
  281.             else
  282.                 behind = this->GetBehindWindowPtr();
  283.             if (qNeedsColorQD || gConfiguration.hasColorQD)
  284.                 aWMgrWindow = (WindowPtr)NewCWindow(NULL, bounds, templateData.title, FALSE, templateData.procID, behind, templateData.hasGoAway, ((long)this));
  285.             else
  286.                 aWMgrWindow = NewWindow(NULL, bounds, templateData.title, FALSE, templateData.procID, behind, templateData.hasGoAway, ((long)this));
  287.             fWMgrWindow = aWMgrWindow;
  288.  
  289.             fIsResizable = templateData.resizable;
  290.             if (templateData.resizable)
  291.                 this->AddAdorner(gResizeIconAdorner, kLowestAdornPriority, FALSE);
  292.             fIsClosable = templateData.hasGoAway;
  293.             fTargetID = templateData.targetID;
  294.             fIsModal = templateData.isModal;
  295.             fDoFirstClick = templateData.doFirstClick;
  296.             fFreeOnClosing = templateData.freeOnClosing;
  297.             fDisposeOnFree = templateData.disposeOnFree;
  298.             fClosesDocument = templateData.closesDocument;
  299.             fOpenInitially = templateData.openInitially;
  300.             this->SetResizeLimits(gStdWSizeRect[topLeft], gStdWSizeRect[botRight]);
  301.             this->BuildWindowRgns(this->BuildWindowRgns(kBuild));// sets fContRgnInset && fContDifference 
  302.  
  303.             this->GetTitle(aString);
  304.             if (ParseTitleTemplate(aString, preDocname, constTitle))
  305.                 SetWTitle(fWMgrWindow, aString);
  306.             fPreDocname = preDocname;
  307.             fConstTitle = constTitle;
  308.  
  309.             this->InstallDocument(itsDocument);
  310.  
  311.             this->AddAdorner(gEraseAdorner, kHighestAdornPriority, FALSE);
  312.  
  313.             fi.Success();
  314.         }
  315.         else                                    // Recover
  316.             {
  317.                 this->Free();
  318.                 fi.ReSignal();
  319.             }
  320.  
  321.         fMustAdapt = templateData.mustAdaptToScreen;
  322.         fMustHorzCenter = templateData.horzCenter;
  323.         fMustVertCenter = templateData.vertCenter;
  324.         fMustStagger = templateData.stagger;
  325.         fMustForceOnScreen = templateData.mustForceOnScreen;
  326.  
  327.         OffsetPtrWStr(itsParams, sizeof(WindowTemplate));
  328.     }
  329. }
  330.  
  331. //--------------------------------------------------------------------------------------------------
  332. #pragma segment MAOpen
  333.  
  334. pascal WindowPtr TWindow::GetBehindWindowPtr(void)
  335. {
  336.     WindowPtr behind = GetLastFloatingWindowPtr();
  337.     if (!behind)
  338.         behind = (WindowPtr)(-1);                // bring the window up in front of all other
  339.                                                 // windows
  340.     return behind;
  341. }
  342.  
  343. //--------------------------------------------------------------------------------------------------
  344. #pragma segment MAWriteRes
  345.  
  346. pascal void TWindow::WRes(ViewRsrcHandle theResource,
  347.                           Ptr& itsParams)        // override 
  348. {
  349.     Str255 theTitle;
  350.  
  351.     inherited::WRes(theResource, itsParams);
  352.  
  353.     this->GetTitle(theTitle);
  354.  
  355.     {
  356.         WindowTemplate & templateData = *((WindowTemplate *)ExpandPtrWStr((Handle)theResource, itsParams, sizeof(WindowTemplate), theTitle.Length()));
  357.  
  358.         templateData.procID = fProcID;
  359.         templateData.hasGoAway = fIsClosable;
  360.         templateData.resizable = fIsResizable;
  361.         templateData.isModal = fIsModal;
  362.         templateData.doFirstClick = fDoFirstClick;
  363.         templateData.freeOnClosing = fFreeOnClosing;
  364.         templateData.disposeOnFree = fDisposeOnFree;
  365.         templateData.closesDocument = fClosesDocument;
  366.         templateData.openInitially = fOpenInitially;
  367.         templateData.mustAdaptToScreen = fMustAdapt;
  368.         templateData.stagger = fMustStagger;
  369.         templateData.mustForceOnScreen = fMustForceOnScreen;
  370.         templateData.vertCenter = fMustVertCenter;
  371.         templateData.horzCenter = fMustHorzCenter;
  372.         templateData.targetID = fTargetID;
  373.         templateData.title = theTitle;
  374.     }
  375. }
  376.  
  377. //--------------------------------------------------------------------------------------------------
  378. #pragma segment MAWriteRes
  379.  
  380. pascal void TWindow::WriteRes(ViewRsrcHandle theResource,
  381.                               Ptr& itsParams)    // override 
  382. {
  383.     gWResSignature = 'wind';
  384.     gWResType = "TWindow";
  385.     this->WRes(theResource, itsParams);
  386. }
  387.  
  388. //--------------------------------------------------------------------------------------------------
  389. #pragma segment MAClose
  390.  
  391. pascal void TWindow::Free(void)                    // override 
  392. {
  393.     Boolean disposeOnFree = fDisposeOnFree;;
  394.     WindowPtr wmgrWindow = fWMgrWindow;
  395.  
  396.     fWMgrWindow = NULL;                            // ??? will this help? 
  397.  
  398.     if (fDocument)
  399.         fDocument->DeleteWindow(this);
  400.     else
  401.         gApplication->DeleteFreeWindow(this);
  402.  
  403.     inherited::Free();
  404.  
  405.     // ****** DON'T REFER TO ANY FIELDS || METHODS OF this ****** 
  406.  
  407.     wmgrWindow = FreeIfWMgrWindow(wmgrWindow, disposeOnFree);
  408. }
  409.  
  410. //--------------------------------------------------------------------------------------------------
  411. #pragma segment MAActivate
  412.  
  413. pascal void TWindow::Activate(Boolean entering)
  414. {
  415.     HiliteWindow(fWMgrWindow, entering);        // make the window "look" active 
  416.  
  417.     Boolean different = (entering != this->IsActive());
  418.     if (different)
  419.     {
  420.         inherited::Activate(entering);
  421.  
  422.         fIsActive = entering;
  423.  
  424.         if (!(fFloats && (fTarget == this)))
  425.             if (entering)
  426.             {
  427.                 gApplication->SetTarget(fTarget);
  428.             }
  429.             else
  430.             {
  431.                 gApplication->SetTarget(gApplication);
  432.             }
  433.     }
  434. }
  435.  
  436. //--------------------------------------------------------------------------------------------------
  437. #pragma segment MAOpen
  438.  
  439. pascal void TWindow::AdaptToScreen(void)
  440. {
  441.     const short stdHScreen = 512;
  442.     const short stdVScreen = 342;
  443.  
  444.     Point diff;
  445.     VRect theFrame;
  446.     VPoint newSize;
  447.     Rect theLimits;
  448.  
  449.     fAdapted = TRUE;                            // We adapted to the screen 
  450.     // Compute pixel difference between current screen and std Mac screen 
  451.     {    // !!! Calculation written as two separate expressions so that Point's "-" operator can be inline.
  452.         Point screenBitsDiff(qd.screenBits.bounds[botRight] - qd.screenBits.bounds[topLeft]);
  453.         diff = screenBitsDiff - Point(stdVScreen, stdHScreen);
  454.     }
  455.  
  456.     this->GetFrame(theFrame);
  457.  
  458.     // If screen is larger, enlarge the window. If the window is too large, shrink it 
  459.     if ((diff != gZeroPt) || (theFrame.bottom > qd.screenBits.bounds.bottom) || (theFrame.right > qd.screenBits.bounds.right))// do an adjustment for larger screen
  460.     {
  461.         // the window adapted to the new screen size by proportion. 
  462.         newSize.h = Fix2Long(FixMul(Long2Fix(fSize.h), FixDiv(Long2Fix(stdHScreen + diff.h), Long2Fix(stdHScreen))));
  463.         newSize.v = Fix2Long(FixMul(Long2Fix(fSize.v), FixDiv(Long2Fix(stdVScreen + diff.v), Long2Fix(stdVScreen))));
  464.  
  465.         // Consider the location of the window, bound it by the resize limits 
  466.         newSize.ConstrainTo(fResizeLimits);
  467.  
  468.         this->Resize(newSize, kInvalidate);
  469.  
  470.     }
  471. }
  472.  
  473. //--------------------------------------------------------------------------------------------------
  474. #pragma segment MAWindowRes
  475.  
  476. pascal Boolean TWindow::AllowsMenuAccess(void)
  477. {
  478.     // Default is to always allow menu access, even if modal 
  479.     return TRUE;
  480. }
  481.  
  482. //--------------------------------------------------------------------------------------------------
  483. #pragma segment MANonRes
  484.  
  485. pascal Handle GetAndLoadWDefProc(Handle windowDefProc)
  486. // utility routine: given a windowDefProc, this routine returns its actual address and loads it 
  487. {
  488.     Handle wDefProc = (Handle)(StripLong(windowDefProc));// strip the variant code 
  489.  
  490.     if ((*wDefProc))                    // if Master Ptr is NULL => resource is purged
  491.         return wDefProc;
  492.     else
  493.     {
  494.         LoadResource(wDefProc);
  495.         if (ResError() == noErr)                // only return it if the LoadResource worked
  496.             return wDefProc;
  497.         else
  498.             return NULL;
  499.     }
  500. }
  501.  
  502. //--------------------------------------------------------------------------------------------------
  503.  
  504. pascal long CallWDefProc(short varCode,
  505.                          WindowPtr theWindow,
  506.                          short message,
  507.                          long param,
  508.                          Handle wDefProc) = {
  509.                                              0x205F,// MOVE.L (A7)+,A0 
  510.                                              0x2050,// MOVE.L (A0),A0 
  511.                                              0x4E90// JSR (A0) 
  512.                                              };
  513. //--------------------------------------------------------------------------------------------------
  514. #pragma segment MAOpen
  515.  
  516. pascal void TWindow::Center(Boolean horizontally,
  517.                             Boolean vertically,
  518.                             Boolean forDialog)
  519. {
  520.     Point windowSize;
  521.     Point screenSize;
  522.     Point contentSize;
  523.     VRect theFrame;
  524.     Rect screenRect;
  525.     Boolean rgnsWereBuilt;
  526.  
  527.     fHorzCentered = horizontally;
  528.     fVertCentered = vertically;
  529.     if ((fWMgrWindow) && (horizontally || vertically))
  530.     {
  531.         this->GetMaxIntersectedDevice(screenRect);
  532.         screenSize.h = screenRect.Length(hSel);
  533.         screenSize.v = screenRect.Length(vSel);/* NOTE: GetMaxIntersectedDevice accounts for
  534.                                                   menubar so don't subtract GetMBarHeight */
  535.  
  536.         rgnsWereBuilt = this->BuildWindowRgns(kBuild);
  537.         {
  538.             Rect & strucBounds = (*(((WindowPeek)fWMgrWindow)->strucRgn))->rgnBBox;// WITH
  539.             windowSize = Point(strucBounds.Length(vSel), strucBounds.Length(hSel));
  540.         }
  541.         this->BuildWindowRgns(rgnsWereBuilt);
  542.  
  543.         this->GetFrame(theFrame);
  544.  
  545.         contentSize = Point((short)theFrame.Length(vSel), (short) theFrame.Length(hSel));
  546.  
  547.         // The top-left content inset isn't enough; factor in the amount to the right of the 
  548.         // content also. 
  549.         {    // Write this calculation as two so that CFront won't inline Point's "-" operator.
  550.             Point windowInset(windowSize - contentSize);
  551.             Point bottomRightInset(windowInset - fContRgnInset);
  552.             fContRgnInset -= bottomRightInset;
  553.         }
  554.  
  555.         if (horizontally)
  556.             theFrame.left = (screenSize.h - contentSize.h + fContRgnInset.h) / 2;
  557.         if (vertically)
  558.             if (forDialog)
  559.             // Put it in the top third of the screen 
  560.                 theFrame.top = ((screenSize.v - contentSize.v + fContRgnInset.v) / 3) + 20;
  561.             else
  562.                 theFrame.top = ((screenSize.v - contentSize.v + fContRgnInset.v) / 2) + 20;
  563.  
  564.         this->Locate(theFrame[topLeft], kDontInvalidate);
  565.     }
  566. }
  567.  
  568. //--------------------------------------------------------------------------------------------------
  569. #pragma segment MAClose
  570.  
  571. pascal void TWindow::Close(void)                // override 
  572.  
  573. {
  574.     inherited::Close();
  575.  
  576.     this->Show(FALSE, kRedraw);
  577.  
  578.     if (fFreeOnClosing)
  579.         this->Free();
  580. }
  581.  
  582. //--------------------------------------------------------------------------------------------------
  583. #pragma segment MAClose
  584.  
  585. pascal void TWindow::CloseByUser(void)
  586. {
  587.     if (fDocument)                        // free window 
  588.         fDocument->CloseView(this);
  589.     else
  590.         this->Close();
  591. }
  592.  
  593. //--------------------------------------------------------------------------------------------------
  594. #pragma segment MAWindowRes
  595.  
  596. pascal void TWindow::DoKeyCommand(TToolboxEvent* event)// override 
  597. {
  598.     inherited::DoKeyCommand(event);
  599. }
  600.  
  601. //--------------------------------------------------------------------------------------------------
  602. #pragma segment MASelCommand
  603.  
  604. pascal void TWindow::DoMenuCommand(CmdNumber aCmdNumber)// override 
  605. {
  606.     switch (aCmdNumber)
  607.     {
  608.         case cClose:
  609.             Boolean oldObjectPerm;
  610.             oldObjectPerm = AllocateObjectsFromPerm(FALSE);// Guarantee the allocation 
  611.             TCloseWindowCommand * aCloseWindowCommand = new TCloseWindowCommand;
  612.             AllocateObjectsFromPerm(oldObjectPerm);
  613.  
  614.             aCloseWindowCommand->ICloseWindowCommand(aCmdNumber, this);
  615.             this->PostCommand(aCloseWindowCommand);
  616.             break;
  617.  
  618.         default:
  619.             inherited::DoMenuCommand(aCmdNumber);
  620.             break;
  621.     }
  622. }
  623.  
  624. //--------------------------------------------------------------------------------------------------
  625. #pragma segment MAWindowRes
  626.  
  627. pascal void TWindow::DoSetupMenus(void)            // override 
  628. {
  629.     if (!fIsModal)                                // Don't enable menu/app commands if modal 
  630.     {
  631.         Enable(cClose, fIsClosable);            // window objects take care of themselves! 
  632.  
  633.         inherited::DoSetupMenus();
  634.     }
  635. }
  636.  
  637. //--------------------------------------------------------------------------------------------------
  638. #pragma segment MAWindowRes
  639.  
  640. pascal Boolean TWindow::HandlesCursor(void)        // override 
  641. {
  642.     return (fHandlesCursor && (this->IsActive() || fDoFirstClick));
  643. }
  644.  
  645. //--------------------------------------------------------------------------------------------------
  646. #pragma segment MAWindowRes
  647.  
  648. pascal Boolean TWindow::LetsSubViewsHandleCursor(void)// override 
  649. {
  650.     return (fLetsSubViewsHandleCursor && (this->IsActive() || fDoFirstClick));
  651. }
  652.  
  653. //--------------------------------------------------------------------------------------------------
  654. #pragma segment MAWindowRes
  655.  
  656. pascal Boolean TWindow::HandlesHelp(void)        // override 
  657. {
  658.     return (fHandlesHelp && this->IsActive());
  659. }
  660.  
  661. //--------------------------------------------------------------------------------------------------
  662. #pragma segment MAWindowRes
  663.  
  664. pascal Boolean TWindow::LetsSubViewsHandleHelp(void)// override 
  665. {
  666.     return (fLetsSubViewsHandleHelp && this->IsActive());
  667. }
  668.  
  669. //--------------------------------------------------------------------------------------------------
  670. #pragma segment MAWindowRes
  671.  
  672. pascal void TWindow::DrawResizeIcon(void)
  673. {
  674.     if (fIsResizable && this->Focus())
  675.     {
  676.         Rect r;
  677.  
  678.         this->GetQDExtent(r);
  679.         r[topLeft] = r[botRight] - Point(kSBarSizeMinus1, kSBarSizeMinus1);
  680.     
  681.         // clip down and avoid drawing the lines that delimit scroll bars
  682. #if qDebug
  683.         UseTempRgn("TWindow::DrawResizeIcon");
  684. #endif
  685. #if qDebug
  686.         UseTempRgn2("TWindow::DrawResizeIcon");
  687. #endif
  688.  
  689.  
  690.         // Avoid drawing the GrowIcon if it would have been clipped
  691.         GetClip(gTempRgn);
  692.         RectRgn(gTempRgn2, r);
  693.         SectRgn(gTempRgn2, gTempRgn, gTempRgn2);
  694.         if (!EmptyRgn(gTempRgn2))
  695.         {
  696.             SetClip(gTempRgn2);
  697.             PenNormal();
  698.             DrawGrowIcon(fWMgrWindow);
  699.             SetClip(gTempRgn);
  700.         }
  701.     
  702. #if qDebug
  703.         DoneWithTempRgn2();
  704. #endif
  705. #if qDebug
  706.         DoneWithTempRgn();
  707. #endif
  708.     }
  709. }
  710.  
  711. //--------------------------------------------------------------------------------------------------
  712. #pragma segment MAWindowRes
  713.  
  714. pascal Boolean TWindow::Focus(void)                // override 
  715. {
  716.     if (this->IsFocused())                        // Already focused 
  717.     {
  718. #if qDebug
  719.         GrafPtr currentPort;
  720.  
  721.         GetPort(currentPort);
  722.         if (this->GetGrafPort() != currentPort)
  723.             ProgramBreak("TWindow.Focus: Port is incorrect");
  724. #endif
  725.  
  726.     }
  727.     else if (fWMgrWindow)                // do my own focus 
  728.     {
  729.         // Set the port 
  730.         GrafPtr currentPort;
  731.         GrafPtr theWindowPort = this->GetGrafPort();
  732.  
  733.         GetPort(currentPort);
  734.         if (currentPort != theWindowPort)
  735.             SetPort(theWindowPort);
  736.  
  737.         SetOrigin(fQDOrigin.h, fQDOrigin.v);
  738.         gFocusedView = this;
  739.  
  740.         // Add the clipping.  Clip either to the visrgn or the update region depending on whether
  741.         // there is an invalid area.
  742.         RgnHandle theUpdateRgn = ((WindowPeek)fWMgrWindow)->updateRgn;
  743.         if (!EmptyRgn(theUpdateRgn))
  744.         {
  745.             // The update region is in global coords but the clip is in local coords.
  746.             // Offset the region to make it in local coords here and restore it there
  747.             // to save copying it
  748.             SuperToLocalRgn(theUpdateRgn);
  749. #if qDebug
  750.             UseTempRgn("TWindow::Focus");
  751. #endif
  752.  
  753.             if (fUpdating)                        // clip TO the update region 
  754.                 SectRgn(theWindowPort->visRgn, theUpdateRgn, gTempRgn);
  755.             else                                // clip OUT the update region 
  756.                 DiffRgn(theWindowPort->visRgn, theUpdateRgn, gTempRgn);
  757.             SetClip(gTempRgn);
  758. #if qDebug
  759.             DoneWithTempRgn();
  760. #endif
  761.             LocalToSuperRgn(theUpdateRgn);
  762.         }
  763.         else
  764.             SetClip(theWindowPort->visRgn);
  765.     }
  766.     else
  767.         return FALSE;
  768.     return TRUE;
  769. }
  770.  
  771. //--------------------------------------------------------------------------------------------------
  772. #pragma segment MAWindowRes
  773.  
  774. pascal Boolean TWindow::FocusOnSuperView(void)    // override 
  775. {
  776.     return FALSE;
  777. }
  778.  
  779. //--------------------------------------------------------------------------------------------------
  780. #pragma segment MAOpen
  781. //!!! Former nested routine, now a private method
  782. pascal void TWindow::GetLocationAdjustment(Point& delta)
  783. {
  784.     const short kMinDragArea = 4;                //!!! Put this in the header
  785.     Rect visScreenRect;
  786.     VRect theVFrame;
  787.                                         
  788.     this->GetFrame(theVFrame);
  789.     Rect theFrame(theVFrame);
  790.  
  791.  
  792.     /* since we don't _really_ know what the drag rgn is, we'll assume that moving the topleft
  793.       pt of the window on screen is sufficient to make it draggable, so calculate the deltas
  794.       necessary to move the topleft pt into visible screen rect */
  795.  
  796.     this->GetMaxIntersectedDevice(visScreenRect);// NOTE: uses gTempRgn 
  797.     visScreenRect.Inset(Point(kMinDragArea, kMinDragArea));
  798.  
  799.     if (theFrame.top < visScreenRect.top)
  800.         delta.v = visScreenRect.top - theFrame.top + fContRgnInset.v;
  801.     else if (theFrame.top > visScreenRect.bottom)
  802.         delta.v = visScreenRect.bottom - theFrame.top - fContRgnInset.v;
  803.  
  804.     if (theFrame.left < visScreenRect.left)
  805.         delta.h = visScreenRect.left - theFrame.left + fContRgnInset.h;
  806.     else if (theFrame.left > theFrame.right)
  807.         delta.h = visScreenRect.right - theFrame.right - fContRgnInset.h;
  808. }
  809.  
  810.  
  811. pascal void TWindow::ForceOnScreen(void)
  812.  
  813. /* ForceOnScreen guarantees that some minimal drag area is accessible to the user, to be dragged
  814.   to the desired location. */
  815.  
  816.  
  817. {
  818.     const short kMinDragArea = 4;                // ??? should this be settable? 
  819.  
  820.     fForcedOnScreen = TRUE;
  821.  
  822.     /* On many systems (including Color QD && the Radius FPD), it's possible to have a
  823.       non-rectangular desktop.    Try to be nice to people who saved windows
  824.       on secondary screens.  GrayRgn is the true indicator of the shape
  825.       of the desktop--screenBits.bounds is the size of the screen with the
  826.       menu bar on it. */
  827.  
  828. #if qDebug
  829.     UseTempRgn("ForceOnScreen");
  830. #endif
  831.  
  832.     Boolean rgnsWereBuilt = this->BuildWindowRgns(kBuild);
  833.     WindowRecord & theWindowRecord = *((WindowPeek)fWMgrWindow);
  834.     {
  835.         DiffRgn(theWindowRecord.strucRgn, theWindowRecord.contRgn, gTempRgn);/* strucRgn less contRgn ≈≈ drag rgn */
  836.         if (EmptyRgn(gTempRgn))
  837.             CopyRgn(theWindowRecord.strucRgn, gTempRgn);// at least get the strucRgn 
  838.     }
  839.     this->BuildWindowRgns(rgnsWereBuilt);
  840.  
  841.     // get the desktop rgn, inset by a minimal drag area 
  842.     RgnHandle aTempRgn = MakeNewRgn();
  843.     CopyRgn(GetGrayRgn(), aTempRgn);            // aTempRgn = desktop rgn 
  844.     InsetRgn(aTempRgn, kMinDragArea, kMinDragArea);// inset aTempRgn 
  845.     SectRgn(gTempRgn, aTempRgn, aTempRgn);        // do drag rgn && desktop rgn instersect ? 
  846. #if qDebug
  847.     DoneWithTempRgn();                            // (GetLocationAdjustment needs gTempRgn) 
  848. #endif
  849.  
  850.     Point delta(gZeroPt);
  851.  
  852.     if (EmptyRgn(aTempRgn) ||!IsDraggable((*aTempRgn)->rgnBBox))
  853.         this->GetLocationAdjustment(delta);// no => adjust the window's location 
  854.  
  855.     DisposeRgn(aTempRgn);
  856.  
  857.     this->Locate(Point(fLocation) + delta, kDontInvalidate);
  858. }
  859.  
  860. //--------------------------------------------------------------------------------------------------
  861. #pragma segment MANonRes
  862.  
  863. pascal GDHandle TWindow::GetMaxIntersectedDevice(Rect& screenRect)
  864. {
  865.     if (qNeedsColorQD || gConfiguration.hasColorQD)//!!! Formerly a nested routine
  866.     {
  867.         GDHandle aGDHandle;
  868.         GDHandle maxSectGD;
  869.         Rect globalStrucRect;
  870.         Rect aGDScreenRect;
  871.         Rect gdSectRect;
  872.         Rect dontCare;
  873.         long sectArea;
  874.         long maxSectArea;
  875.         Rect moveBounds;
  876.         Boolean rgnsWereBuilt;
  877.  
  878.         rgnsWereBuilt = this->BuildWindowRgns(kBuild);/* sets fContRgnInset && fContDifference, and
  879.                                                   make sure contrgn and strucrgn are
  880.                                                   available */
  881.         globalStrucRect = (*(((WindowPeek)fWMgrWindow)->strucRgn))->rgnBBox;
  882.         this->BuildWindowRgns(rgnsWereBuilt);
  883.  
  884.         moveBounds = fMoveBounds;
  885.  
  886.         aGDHandle = GetDeviceList();
  887.         maxSectGD = GetMainDevice();            // set as best choice default 
  888.         maxSectArea = 0;
  889.         while (aGDHandle)
  890.         {                                        /* calc which scrn intersects largest part of
  891.                                                   window */
  892.             aGDScreenRect = (*aGDHandle)->gdRect;
  893.             if (SectRect(aGDScreenRect, moveBounds, dontCare) && SectRect(globalStrucRect, aGDScreenRect, gdSectRect))
  894.             {
  895.                 sectArea = IntMultiply(gdSectRect.Length(vSel), gdSectRect.Length(hSel));
  896.                 if (sectArea > maxSectArea)        // do we have a new winner? 
  897.                 {
  898.                     maxSectArea = sectArea;
  899.                     maxSectGD = aGDHandle;
  900.                 }
  901.             }
  902.             aGDHandle = GetNextDevice(aGDHandle);
  903.         }
  904.  
  905.         if (maxSectGD != GetMainDevice())
  906.             screenRect = (*maxSectGD)->gdRect;
  907.         else
  908.         {                                        /* Account for menu bar on the main screen.
  909.                                                   Don't just assume that its at the top of
  910.                                                   the screen! */
  911. #if qDebug
  912.             UseTempRgn("TWindow.GetMaxIntersectedDevice");
  913. #endif
  914.  
  915.             RectRgn(gTempRgn, (*maxSectGD)->gdRect);// main screen with menubar 
  916.             SectRgn(gTempRgn, GetGrayRgn(), gTempRgn);// GetGrayRgn == desktop rgn w/o menubar 
  917.             screenRect = (*gTempRgn)->rgnBBox;    // => main screen w/o menubar 
  918. #if qDebug
  919.             DoneWithTempRgn();
  920. #endif
  921.  
  922.         }
  923.         return maxSectGD;
  924.     }
  925.     else
  926.     {                                            /* Account for menu bar on the main screen.
  927.                                                   Don't just assume that its at the top of
  928.                                                   the screen! */
  929. #if qDebug
  930.         UseTempRgn("TWindow.GetMaxIntersectedDevice");
  931. #endif
  932.  
  933.         RectRgn(gTempRgn, qd.screenBits.bounds);// main screen with menubar 
  934.         SectRgn(gTempRgn, GetGrayRgn(), gTempRgn);// GetGrayRgn == desktop rgn w/o menubar 
  935.         screenRect = (*gTempRgn)->rgnBBox;        // => main screen w/o menubar 
  936. #if qDebug
  937.         DoneWithTempRgn();
  938. #endif
  939.  
  940.         return NULL;                            // we only have GDHandle in CQD world 
  941.     }
  942. }
  943.  
  944. //--------------------------------------------------------------------------------------------------
  945. #pragma segment MAInspector
  946.  
  947. pascal void TWindow::GetInspectorName(Str255& inspectorName)// override 
  948. {
  949.     if ((fWMgrWindow) && (!(((long)fWMgrWindow) & 1)))// NOT ODD (fWMgrWindow)
  950.         this->GetTitle(inspectorName);
  951. }
  952.  
  953. //--------------------------------------------------------------------------------------------------
  954. #pragma segment MAWindowRes
  955.  
  956. pascal GrafPtr TWindow::GetGrafPort(void)        // override 
  957. {
  958.     if (gPrinting || gDrawingPictScrap)
  959.         return qd.thePort;                        //thePort assumed to be set by print handler
  960.     else
  961.         return ((GrafPtr)fWMgrWindow);            // if it's NULL it's NULL
  962. }
  963.  
  964. //--------------------------------------------------------------------------------------------------
  965. #pragma segment MAWindowRes
  966.  
  967. pascal TEvtHandler* TWindow::GetTarget(void)
  968. {
  969.     return fTarget;
  970. }
  971.  
  972. //--------------------------------------------------------------------------------------------------
  973. #pragma segment MAWindowRes
  974.  
  975. pascal void TWindow::GetTitle(Str255& theTitle)
  976. {
  977.     if (fWMgrWindow)
  978.         GetWTitle(fWMgrWindow, theTitle);
  979.     else
  980.         theTitle = "";
  981. }
  982.  
  983. //--------------------------------------------------------------------------------------------------
  984. #pragma segment MAWindowRes
  985.  
  986. pascal TWindow* TWindow::GetWindow(void)        // override 
  987. {
  988.     return this;
  989. }
  990.  
  991. //--------------------------------------------------------------------------------------------------
  992. #pragma segment MAClose
  993.  
  994. pascal void TWindow::GoAwayByUser(const VPoint& theMouse)
  995. {
  996.     VPoint globalVMouse(theMouse);
  997.  
  998.     this->LocalToSuper(globalVMouse);
  999.  
  1000.     if (fIsClosable && TrackGoAway(fWMgrWindow, globalVMouse))
  1001.     {
  1002.         Boolean oldObjectPerm;
  1003.         oldObjectPerm = AllocateObjectsFromPerm(FALSE);// Guarantee the allocation 
  1004.         TCloseWindowCommand * aCloseWindowCommand = new TCloseWindowCommand;
  1005.         AllocateObjectsFromPerm(oldObjectPerm);
  1006.  
  1007.         aCloseWindowCommand->ICloseWindowCommand(cClose, this);
  1008.         this->PostCommand(aCloseWindowCommand);
  1009.     }
  1010. }
  1011.  
  1012. //--------------------------------------------------------------------------------------------------
  1013. #pragma segment MASelCommand
  1014.  
  1015. pascal Boolean TWindow::HandleMouseDown(const VPoint& theMouse,
  1016.                                         TToolboxEvent* event,
  1017.                                         Point hysteresis)// override 
  1018. {
  1019.     Boolean dispatchByPartCode;
  1020.     short aPartCode;
  1021.     Boolean result;
  1022.  
  1023.  
  1024.     result = TRUE;
  1025.  
  1026.     // find out where the mouse was pressed 
  1027.     aPartCode = this->GetPartCode(theMouse);
  1028.  
  1029.     /* note the following workaround special case for inactive windows that want the first
  1030.       click - GetPartCode will tell us that the mouse was pressed "inContent" so we should
  1031.       select the window, and then call GetPartCode again to find out where the mouse was
  1032.      *really* pressed */
  1033.     dispatchByPartCode = TRUE;
  1034.     if ((gApplication->GetActiveWindow() != this) && (aPartCode == inContent))
  1035.     {
  1036.         this->Select();
  1037.  
  1038.         if (fDoFirstClick)
  1039.         {
  1040.             gApplication->UpdateAllWindows();
  1041.             aPartCode = this->GetPartCode(theMouse);// now, where is the mouse 
  1042.         }
  1043.         else
  1044.             dispatchByPartCode = FALSE;
  1045.     }
  1046.  
  1047.     // dispatch according to where the mouse was pressed 
  1048.     if (dispatchByPartCode)
  1049.         switch (aPartCode)
  1050.         {
  1051.             case inContent:
  1052.                 result = inherited::HandleMouseDown(theMouse, event, hysteresis);
  1053.                 break;
  1054.  
  1055.             case inDrag:
  1056.                 this->MoveByUser(theMouse);
  1057.                 break;
  1058.  
  1059.             case inGrow:
  1060.                 this->ResizeByUser(theMouse);
  1061.                 break;
  1062.  
  1063.             case inGoAway:
  1064.                 this->GoAwayByUser(theMouse);
  1065.                 break;
  1066.  
  1067.             case inZoomIn:
  1068.             case inZoomOut:
  1069.                 this->ZoomByUser(theMouse, aPartCode);
  1070.                 break;
  1071.  
  1072.             case inDesk:
  1073.                 break;
  1074.  
  1075.         }
  1076.     else
  1077.         result = FALSE;
  1078.     return result;
  1079. }
  1080.  
  1081. //--------------------------------------------------------------------------------------------------
  1082. #pragma segment MAWindowRes
  1083.  
  1084. pascal Boolean TWindow::HasPendingUpdate(void)
  1085. {
  1086.     return !EmptyRgn(((WindowPeek)fWMgrWindow)->updateRgn);
  1087. }
  1088.  
  1089. //--------------------------------------------------------------------------------------------------
  1090. #pragma segment MAWindowRes
  1091.  
  1092. pascal short TWindow::GetPartCode(const VPoint& theMouse)// override 
  1093. {
  1094.     WindowPtr aWMgrWindow;
  1095.     short partCode;
  1096.     VPoint globalVWhere(theMouse);
  1097.  
  1098.     this->LocalToSuper(globalVWhere);
  1099.  
  1100.     // Call FindWindow to determine the partcode 
  1101.     partCode = FindWindow(globalVWhere, aWMgrWindow);
  1102.     if (aWMgrWindow != fWMgrWindow)                // if we fail this sanity check, then 
  1103.     {
  1104.         if (qDebug)
  1105.             ProgramBreak("in TWindow.GetPartCode: passed a VPoint that didn''t belong to the window");
  1106.         return inDesk;                            // …we don't really know where it is! 
  1107.     }
  1108.     else
  1109.         return partCode;                        /* passed the sanity check so return the part
  1110.                                                   code we got back from FindWindow */
  1111. }
  1112.  
  1113. //--------------------------------------------------------------------------------------------------
  1114. #pragma segment MAOpen
  1115.  
  1116. pascal void TWindow::InstallDocument(TDocument* itsDocument)
  1117. {
  1118.     Str255 aString;
  1119.  
  1120.     fDocument = itsDocument;
  1121.     if (itsDocument)
  1122.     {
  1123.         gApplication->DeleteFreeWindow(this);    // Just in case… 
  1124.         itsDocument->AddWindow(this);
  1125.         itsDocument->GetTitle(aString);
  1126.         if (!aString.IsEmpty())                    // not an untitled document 
  1127.             this->SetTitleForDoc(aString);
  1128.         fNextHandler = itsDocument;
  1129.     }
  1130.     else
  1131.     {
  1132.         gApplication->AddFreeWindow(this);
  1133.         fNextHandler = gApplication;
  1134.     }
  1135. }
  1136.  
  1137. //--------------------------------------------------------------------------------------------------
  1138. #pragma segment MANonRes
  1139.  
  1140. pascal Boolean TWindow::IsDismissed(void)
  1141. {
  1142.     return fDismissed;
  1143. }
  1144.  
  1145. //--------------------------------------------------------------------------------------------------
  1146. #pragma segment MANonRes
  1147.  
  1148. pascal void TWindow::Dismiss(void)
  1149. {
  1150.     fDismissed = TRUE;
  1151. }
  1152.  
  1153. //--------------------------------------------------------------------------------------------------
  1154.  
  1155. pascal long PushLong(short h,
  1156.                      short v)
  1157. // This can be used to push a longint given a point.     PushLong(aPt.h,aPt.v); 
  1158.  = {
  1159.     0x2E9F};                                    // MOVE.L (A7)+,(A7) 
  1160.  
  1161. //--------------------------------------------------------------------------------------------------
  1162. #pragma segment MANonRes
  1163.  
  1164. pascal Boolean TWindow::IsDraggable(const Rect& whichRect)
  1165. // Returns TRUE if any of the corner points of whichRect are draggable. 
  1166. {
  1167.     Handle wDefProc;
  1168.     short variant;
  1169.     SignedByte saveState;
  1170.     Boolean rgnsWereBuilt;
  1171.     Boolean result;
  1172.  
  1173.  
  1174.     result = TRUE;
  1175.     wDefProc = GetAndLoadWDefProc(((WindowPeek)fWMgrWindow)->windowDefProc);
  1176.     if (wDefProc)
  1177.     {
  1178.         saveState = LockHandleHigh(wDefProc);
  1179.         rgnsWereBuilt = this->BuildWindowRgns(kBuild);// regions needed for hit testing 
  1180.         variant = GetWindowVariant(fWMgrWindow);
  1181.  
  1182.         if ((CallWDefProc(variant, fWMgrWindow, wHit, PushLong(whichRect.left, whichRect.top), wDefProc) != wInDrag) && (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(whichRect.right, whichRect.bottom), wDefProc) != wInDrag) && (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(whichRect.left, whichRect.bottom), wDefProc) != wInDrag) && (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(whichRect.right, whichRect.top), wDefProc) != wInDrag))
  1183.             result = FALSE;                        // …no, so window _isn't_ draggable 
  1184.  
  1185.         HSetState(wDefProc, saveState);
  1186.         this->BuildWindowRgns(rgnsWereBuilt);
  1187.     }
  1188.     else
  1189.     {
  1190.         if (qDebug)
  1191.             ProgramBreak("###TWindow.IsDraggable: can't load wdef");
  1192.         return FALSE;
  1193.     }
  1194.     return result;
  1195. }
  1196.  
  1197. //--------------------------------------------------------------------------------------------------
  1198. #pragma segment MANonRes
  1199.  
  1200. pascal Boolean TWindow::IsHiddenOnSuspend(void)
  1201. {
  1202.     return fHideOnSuspend;                        /* clipboard windows && floaters should return
  1203.                                                   TRUE (and any other window that wants to
  1204.                                                   get hidden when the application is
  1205.                                                   suspended by the Process Manager). */
  1206. }
  1207.  
  1208. //--------------------------------------------------------------------------------------------------
  1209. #pragma segment MAWindowRes
  1210.  
  1211. pascal Boolean TWindow::IsShown(void)            // override 
  1212. {
  1213.     if (fWMgrWindow)
  1214.         return ((WindowPeek)fWMgrWindow)->visible;
  1215.     else
  1216.         return FALSE;
  1217. }
  1218.  
  1219. //--------------------------------------------------------------------------------------------------
  1220. #pragma segment MAWindowRes
  1221.  
  1222. pascal Boolean TWindow::IsActive(void)            // override 
  1223. {
  1224.     return fIsActive;
  1225. }
  1226.  
  1227. //--------------------------------------------------------------------------------------------------
  1228. #pragma segment MAWindowRes
  1229.  
  1230. pascal void TWindow::DoInvalidateRgn(RgnHandle badRgn)
  1231. {
  1232.     if ((qd.thePort == fWMgrWindow) && this->IsShown())
  1233.         if (!EmptyRgn(badRgn))
  1234.         {
  1235.             InvalRgn(badRgn);
  1236.             if (gShowInvalidations)
  1237.                 FillRgn(badRgn, qd.ltGray);
  1238.  
  1239.             if (fUpdating)                        // clip INCLUDES the update region 
  1240.                 UnionRgn(qd.thePort->clipRgn, badRgn, qd.thePort->clipRgn);
  1241.             else                                // clip EXCLUDES the update region 
  1242.                 DiffRgn(qd.thePort->clipRgn, badRgn, qd.thePort->clipRgn);
  1243.  
  1244.         }
  1245. }
  1246.  
  1247. //--------------------------------------------------------------------------------------------------
  1248. #pragma segment MAWindowRes
  1249.  
  1250. pascal void TWindow::DoValidateRgn(RgnHandle goodRgn)
  1251. {
  1252.     if ((qd.thePort == fWMgrWindow) && this->IsShown())
  1253.         if (!EmptyRgn(goodRgn))
  1254.         {
  1255.             ValidRgn(goodRgn);
  1256.  
  1257.             if (fUpdating)                        // clip INCLUDES the update region 
  1258.                 UnionRgn(qd.thePort->clipRgn, goodRgn, qd.thePort->clipRgn);
  1259.             else                                // clip EXCLUDES the update region 
  1260.                 DiffRgn(qd.thePort->clipRgn, goodRgn, qd.thePort->clipRgn);
  1261.         }
  1262. }
  1263.  
  1264. //--------------------------------------------------------------------------------------------------
  1265. #pragma segment MANonRes
  1266.  
  1267. pascal Boolean TWindow::BuildWindowRgns(Boolean build)
  1268. //  Calculate window size including structure region (i.e. title bar).  To do this
  1269. //  we need to force the window to compute its structure region by calling its defproc,
  1270. //  if the window isn't shown.  If build is FALSE, set the regions back to empty regions, so as not
  1271. //  to confuse the window manager.  Return the previous state of the regions.
  1272.  
  1273. {
  1274.     WindowRecord & theWindowRecord = *((WindowPeek)fWMgrWindow);
  1275.  
  1276.     // The regions are considered to be built if either:
  1277.     //  a) the window is shown; or
  1278.     //  b) the structure rgn is not empty.
  1279.  
  1280.     if (this->IsShown() || !EmptyRgn(theWindowRecord.strucRgn))
  1281.     {
  1282.         if ((build != kBuild) && !this->IsShown())
  1283.         {
  1284.             SetEmptyRgn(theWindowRecord.strucRgn);
  1285.             SetEmptyRgn(theWindowRecord.contRgn);
  1286.         }
  1287.         return kBuild;
  1288.     }
  1289.     else
  1290.     {
  1291.         if (build == kBuild)
  1292.         {
  1293.             Handle wDefProc = GetAndLoadWDefProc(theWindowRecord.windowDefProc);
  1294.             if (wDefProc)
  1295.             {
  1296.                 SignedByte saveState = LockHandleHigh(wDefProc);
  1297.                 CallWDefProc(GetWindowVariant(fWMgrWindow), fWMgrWindow, wCalcRgns, 0, wDefProc);
  1298.                 HSetState(wDefProc, saveState);
  1299.  
  1300.                 // Calculate offset from top-left of window structure to top-left of window content
  1301.                 fContRgnInset = (*theWindowRecord.contRgn)->rgnBBox[topLeft] - (*theWindowRecord.strucRgn)->rgnBBox[topLeft];
  1302.  
  1303.                 Rect globalStrucRect = (*theWindowRecord.strucRgn)->rgnBBox;
  1304.                 Rect globalContRect = (*theWindowRecord.contRgn)->rgnBBox;
  1305.                 fContDifference.v = (globalStrucRect.Length(vSel)) - (globalContRect.Length(vSel));
  1306.                 fContDifference.h = (globalStrucRect.Length(hSel)) - (globalContRect.Length(hSel));
  1307.             }
  1308.         }
  1309.         return !kBuild;
  1310.     }
  1311. }
  1312.  
  1313. //--------------------------------------------------------------------------------------------------
  1314. #pragma segment MAWindowRes
  1315.  
  1316. pascal void TWindow::Locate(const VPoint& newLoc,
  1317.                             Boolean invalidate)    // override 
  1318. {
  1319.     if ((fWMgrWindow) && (newLoc != fLocation))
  1320.         MoveWindow(fWMgrWindow, (short)newLoc.h, (short)newLoc.v, FALSE);
  1321.         // ??? should offset by fContRgnInset.v //!!! VCoordinate->short
  1322.  
  1323.     inherited::Locate(newLoc, invalidate);
  1324. }
  1325.  
  1326. //--------------------------------------------------------------------------------------------------
  1327. #pragma segment MAWindowRes
  1328.  
  1329. pascal void TWindow::Select(void)
  1330. {
  1331.     gApplication->SelectWMgrWindow(fWMgrWindow);
  1332. }
  1333.  
  1334. //--------------------------------------------------------------------------------------------------
  1335. #pragma segment MAWindowRes
  1336.  
  1337. pascal void TWindow::MoveByUser(const VPoint& theMouse)
  1338. {
  1339.     VPoint globalVMouse(theMouse);
  1340.  
  1341.     this->LocalToSuper(globalVMouse);
  1342.  
  1343.     DragWindow(fWMgrWindow, globalVMouse,fMoveBounds);
  1344.  
  1345.     // Don't forget to tell the window object 
  1346.     Point currLoc(fWMgrWindow->portRect[topLeft]);
  1347.     LocalToGlobal(currLoc);        // can't use localtosuper since flocation not updated yet
  1348.     this->Locate(currLoc, kDontInvalidate);
  1349. }
  1350.  
  1351. //--------------------------------------------------------------------------------------------------
  1352. #pragma segment MAOpen
  1353.  
  1354. pascal void TWindow::Open(void)                    // override 
  1355. {
  1356.     if (!this->IsShown())
  1357.     {
  1358.         // Keep us matching the window since we are parallel structures
  1359.         // Be sure all views are sized right
  1360.         this->Resize(VPoint(fWMgrWindow->portRect.Length(vSel), fWMgrWindow->portRect.Length(hSel)), kDontInvalidate);
  1361.  
  1362.         this->AdjustSize();                        // Give non-template views a shot at correcting for sizedeterminers
  1363.  
  1364.         if (fMustAdapt && !fAdapted)
  1365.             this->AdaptToScreen();
  1366.         if ((fMustHorzCenter && !fHorzCentered) || (fMustVertCenter && !fVertCentered))
  1367.             this->Center(fMustHorzCenter, fMustVertCenter, fIsModal);
  1368.         if (fMustStagger && !fStaggered)
  1369.         {
  1370.             /* If both staggering and forcing on screen are specified then we must ensure
  1371.               that the window is forced on screen FIRST so that the staggering will occur
  1372.               in a visible (and usable) location.  BUT, after staggering we must STILL ensure
  1373.               that the window is forced on screen so, we reset the forced flag so that
  1374.               forcing will occur on schedule later. */
  1375.             if (fMustForceOnScreen && !fForcedOnScreen)
  1376.             {
  1377.                 this->ForceOnScreen();
  1378.                 fForcedOnScreen = FALSE;        // Make sure we can be forced again 
  1379.             }
  1380.             this->SimpleStagger(kStdStaggerAmount, kStdStaggerAmount, gStdStaggerCount);
  1381.         }
  1382.         if (fMustForceOnScreen && !fForcedOnScreen)
  1383.             this->ForceOnScreen();
  1384.  
  1385.         // If fVisibleExtent is empty, UpdateCoordinates so our contents will be drawn
  1386.         if (fVisibleExtent.Empty())
  1387.             this->UpdateCoordinates();
  1388.  
  1389.         this->Show(TRUE, kRedraw);                // Make me visible 
  1390.  
  1391.     }
  1392.     inherited::Open();                            // Tell subviews to open in case they care 
  1393. }
  1394.  
  1395. //--------------------------------------------------------------------------------------------------
  1396. #pragma segment MAWindowRes
  1397.  
  1398. pascal void TWindow::PoseModally(void)
  1399. {
  1400.     FailInfo fi;
  1401.     Boolean saveIsModal;
  1402.     
  1403.     VOLATILE(saveIsModal);
  1404.  
  1405.     // let the window "know" it's going to be placed a modal state 
  1406.     saveIsModal = fIsModal;
  1407.     fIsModal = TRUE;
  1408.  
  1409.     gApplication->CommitLastCommand();            // Make sure that the undo menu reflects 
  1410.     // the view being looked at.  Otherwise 
  1411.     // the undo menu will be wrong.        
  1412.  
  1413.     this->Open();
  1414.     this->Select();                                // Bring it to the front 
  1415.  
  1416.     fDismissed = FALSE;
  1417.     while (!this->IsDismissed())
  1418.     {
  1419.         if (fi.Try())
  1420.         {
  1421.             gApplication->PollEvent(kAllowApplicationToSleep);
  1422.             Success(fi);
  1423.         }
  1424.         else                                    // Recover
  1425.             {
  1426.                 if (fi.error != noErr)            // If no error then keep the dialog running 
  1427.                 {
  1428.                     this->Dismiss();            // Avoid validating selected edit text 
  1429.                     this->Close();                /* If an error then close the dialog and exit
  1430.                                                   via failure mechanism */
  1431.  
  1432.                     fIsModal = saveIsModal;
  1433.                     fi.ReSignal();
  1434.                 }
  1435.             }
  1436.     }
  1437.  
  1438.     fIsModal = saveIsModal;
  1439. }
  1440.  
  1441. //--------------------------------------------------------------------------------------------------
  1442. #pragma segment MANonRes
  1443.  
  1444. pascal void TWindow::RemovedASubView(TView* theSubView)// override 
  1445. {
  1446.     // Patch up the target chain. 
  1447.     if (theSubView == fTarget)
  1448.         this->SetTarget(theSubView->fSuperView);//!!! Should we check fSuperView for NULL?
  1449.     else if (theSubView == gApplication->GetTarget())
  1450.         gApplication->SetTarget(theSubView->fSuperView);
  1451.  
  1452. }
  1453.  
  1454. //--------------------------------------------------------------------------------------------------
  1455. #pragma segment MANonRes
  1456.  
  1457. pascal void TWindow::Resize(const VPoint& newSize,
  1458.                             Boolean invalidate)    // override 
  1459. {
  1460.     if (newSize != fSize)
  1461.     {
  1462.         SizeWindow(fWMgrWindow, (short)newSize.h, (short)newSize.v, invalidate);//!!! VCoordinate-> short
  1463.  
  1464.         VRect vr (-kSBarSizeMinus1, -kSBarSizeMinus1,  0, 0);    // standard size of grow box 
  1465.                                                                 // ??? any better way?
  1466.  
  1467.         // the grow box must be invalidated because it intrudes into the window content
  1468.         if (fIsResizable && invalidate)
  1469.             this->InvalidateVRect(vr + fSize);                        // old location
  1470.  
  1471.         inherited::Resize(newSize, invalidate);
  1472.  
  1473.         if (fIsResizable && invalidate)
  1474.             this->InvalidateVRect(vr + fSize);                        // old location
  1475.     }
  1476. }
  1477.  
  1478. //--------------------------------------------------------------------------------------------------
  1479. #pragma segment MANonRes
  1480.  
  1481. pascal void TWindow::ResizeByUser(const VPoint& theMouse)
  1482. {
  1483.     if (fIsResizable)
  1484.     {
  1485.         VPoint globalVMouse(theMouse);
  1486.  
  1487.         this->LocalToSuper(globalVMouse);
  1488.  
  1489.         long growResult = GrowWindow(fWMgrWindow, globalVMouse, fResizeLimits);
  1490.         if (growResult)
  1491.             this->Resize(VPoint(HiWord(growResult),LoWord(growResult)), kInvalidate);
  1492.     }
  1493. }
  1494.  
  1495. //--------------------------------------------------------------------------------------------------
  1496. #pragma segment MAOpen
  1497.  
  1498. pascal void TWindow::SetResizeLimits(Point itsMinSize,
  1499.                                      Point itsMaxSize)
  1500. {
  1501.     fResizeLimits = Rect(itsMinSize, itsMaxSize);
  1502.  
  1503.     // If the window is zoomable, keep the window's state data current 
  1504.     if ((fProcID) & zoomDocProc)
  1505.     {
  1506.         Rect & theStdState = (*((WStateDataHandle)(((WindowPeek)fWMgrWindow)->dataHandle)))->stdState;
  1507.         theStdState.right = (short)Min(theStdState.right, fLocation.h + itsMaxSize.h - 1);//!!! long-> short
  1508.         theStdState.bottom = (short)Min(theStdState.bottom, fLocation.v + itsMaxSize.v - 1);//!!! long-> short
  1509.     }
  1510.  
  1511.     // If the window is not sized within the new limits, resize it to fit
  1512.     VPoint newSize = fSize;
  1513.     newSize.ConstrainTo(fResizeLimits);
  1514.  
  1515.     if (newSize != fSize)
  1516.         this->Resize(newSize, kDontInvalidate);
  1517.  
  1518. }
  1519.  
  1520. //--------------------------------------------------------------------------------------------------
  1521. #pragma segment MAWindowRes
  1522.  
  1523. pascal void TWindow::SetTarget(TEvtHandler* newTarget)// override 
  1524. {
  1525.     long reason;
  1526.     TEvtHandler * currentTarget;
  1527.  
  1528.  
  1529.     if (!newTarget)                        // Would be annoying if a nil got in here! 
  1530.         newTarget = this;
  1531.  
  1532.     /* If the window is active, the application's target is set, otherwise we simply save the new
  1533.       target in the window field */
  1534.     currentTarget = gApplication->GetTarget();
  1535.     if (newTarget != currentTarget) 
  1536.     {
  1537.         if (this->IsActive())    // TRUE for floaters too! 
  1538.         {
  1539.             reason = currentTarget->WillingToResignTarget();
  1540.             if (reason == 0)
  1541.             {
  1542.                 currentTarget->TargetValidationSucceeded();
  1543.  
  1544.                 currentTarget->ResignedWindowTarget();
  1545.                 gApplication->SetTarget(newTarget);
  1546.                 fTarget = newTarget;
  1547.                 newTarget->BecameWindowTarget();
  1548.             }
  1549.             else
  1550.                 currentTarget->TargetValidationFailed(reason);
  1551.         }
  1552.         else
  1553.         {
  1554.             fTarget->ResignedWindowTarget();
  1555.             fTarget = newTarget;
  1556.             fTarget->BecameWindowTarget();
  1557.         }
  1558.     }
  1559. }
  1560.  
  1561. //--------------------------------------------------------------------------------------------------
  1562. #pragma segment MAWindowRes
  1563.  
  1564. pascal void TWindow::SetTitle(const Str255& newTitle)
  1565. {
  1566.     Str255 oldTitle;
  1567.  
  1568.     GetWTitle(fWMgrWindow, oldTitle);            /* to minimize flash, we only set the title
  1569.                                                   if it's different from the current title */
  1570.     if (CompareStrings(oldTitle, newTitle) != sortsEqual)
  1571.         SetWTitle(fWMgrWindow, newTitle);
  1572. }
  1573.  
  1574. //--------------------------------------------------------------------------------------------------
  1575. #pragma segment MAFile
  1576.  
  1577. pascal void TWindow::SetTitleForDoc(const Str255& newDocTitle)
  1578. {
  1579.     Str255 title;
  1580.  
  1581.     if (fPreDocname > 0)                        // optimize for case of nothing to do 
  1582.     {
  1583.         this->GetTitle(title);
  1584.  
  1585.         if (SubstituteInTitle(title, newDocTitle, fPreDocname, fConstTitle))
  1586.             this->SetTitle(title);
  1587.     }
  1588. }
  1589.  
  1590. //--------------------------------------------------------------------------------------------------
  1591. #pragma segment MANonRes
  1592.  
  1593. pascal void TWindow::AboutToLoseControl(void)
  1594. {
  1595.     Boolean oldManageActivation;
  1596.  
  1597.     if (this->IsShown() && this->IsHiddenOnSuspend())
  1598.     {
  1599.         fWasHiddenOnSuspend = TRUE;
  1600.         oldManageActivation = fGenerateActivates;
  1601.         fGenerateActivates = FALSE;
  1602.         this->Show(FALSE, kRedraw);
  1603.         fGenerateActivates = oldManageActivation;
  1604.     }
  1605. }
  1606.  
  1607. //--------------------------------------------------------------------------------------------------
  1608. #pragma segment MANonRes
  1609.  
  1610. pascal void TWindow::RegainControl(void)
  1611. {
  1612.     Boolean oldManageActivation;
  1613.  
  1614.     if (fWasHiddenOnSuspend)
  1615.     {
  1616.         fWasHiddenOnSuspend = FALSE;
  1617.         // !!! Any necessary activation is handled in TApplication.HandleSystemEvent 
  1618.         oldManageActivation = fGenerateActivates;
  1619.         fGenerateActivates = FALSE;
  1620.         this->Show(TRUE, kRedraw);
  1621.         fGenerateActivates = oldManageActivation;
  1622.     }
  1623. }
  1624.  
  1625. //--------------------------------------------------------------------------------------------------
  1626. #pragma segment MANonRes
  1627.  
  1628. pascal void TWindow::Show(Boolean state,
  1629.                           Boolean redraw)        // override 
  1630. {
  1631.     if (state)
  1632.         this->Resize(VPoint(fWMgrWindow->portRect.Length(vSel), fWMgrWindow->portRect.Length(hSel)), redraw);// Be sure all views are sized right 
  1633.  
  1634.     if (fGenerateActivates)
  1635.     {
  1636.         if (state)
  1637.             ShowWindow(fWMgrWindow);
  1638.         else
  1639.             HideWindow(fWMgrWindow);
  1640.     }
  1641.     else
  1642.     {
  1643.         ShowHide(fWMgrWindow, state);
  1644.         if (!state)
  1645.             this->Activate(FALSE);                /* at least de-activate ourselves when hiding
  1646.                                                 */
  1647.     }
  1648.  
  1649.     // manage activation:
  1650.     if (fFloats)
  1651.         this->Activate(state);                    // for floaters, activation == visibility 
  1652.     else if ((!state) && this->IsActive())
  1653.         this->Activate(FALSE);                    // if active, de-activate ourselves when hiding
  1654.  
  1655.     inherited::Show(state, redraw);
  1656. }
  1657.  
  1658. //--------------------------------------------------------------------------------------------------
  1659. #pragma segment MAOpen
  1660.  
  1661. pascal void TWindow::SimpleStagger(short dh,
  1662.                                    short dv,
  1663.                                    short& counter)
  1664. {
  1665.     VRect theFrame;                            // The topLeft of the window must fall in  here. 
  1666.     short nSlots;
  1667.     short slot;
  1668.  
  1669.     fStaggered = TRUE;
  1670.     this->GetFrame(theFrame);
  1671.  
  1672.     theFrame[botRight] = (theFrame[topLeft] + VPoint(fMoveBounds[botRight])) - theFrame[botRight];
  1673.  
  1674.     /* This covers the case of dh && dv both >= 0; if either is less than
  1675.       0, the right (bottom) limit is set to the left (top) edge of the
  1676.       screen -- allowing for some margin.  This makes the right (bottom)
  1677.       edge less than the left (top) edge, but this is OK since the /
  1678.       statement below will be dividing 2 negative numbers. */
  1679.  
  1680.     if (dh < 0)
  1681.         theFrame.right = fMoveBounds.left;
  1682.     if (dv < 0)
  1683.         theFrame.bottom = fMoveBounds.top;
  1684.  
  1685.     // This code avoids divide by zero problems 
  1686.     if (!dh || !dv)
  1687.         nSlots = 0;
  1688.     else
  1689.         nSlots = (short)Min((theFrame.Length(hSel) + dh - 1) / dh, (theFrame.Length(vSel) + dv - 1) / dv);//!!! long-> short
  1690.  
  1691.     if (!nSlots)
  1692.         slot = 0;
  1693.     else
  1694.         slot = counter % nSlots;
  1695.  
  1696.     if (slot)                                // move the window 
  1697.     {
  1698.         // The place to position the window 
  1699.         this->Locate(theFrame[topLeft] + VPoint((slot * dv), (slot * dh)), kDontInvalidate);
  1700.     }
  1701.  
  1702.     ++counter;
  1703. }
  1704.  
  1705. //--------------------------------------------------------------------------------------------------
  1706. #pragma segment MAWindowRes
  1707.  
  1708. pascal void TWindow::Update(void)                // override 
  1709. {
  1710.     if (this->HasPendingUpdate())
  1711.     {
  1712.         fUpdating = TRUE;                        // So TWindow.Focus will know to focus TO the update rgn
  1713.  
  1714.         this->InvalidateFocus();
  1715. //        this->InvalidateRgn(((WindowPeek)fWMgrWindow)->updateRgn);
  1716. //        CopyRgn(((WindowPeek)fWMgrWindow)->updateRgn, gTempRgn2);
  1717. //        this->SuperToLocalRgn(gTempRgn2);
  1718. //        this->InvalidateRgn(gTempRgn2);
  1719.  
  1720.         FailInfo fi;
  1721.         if (fi.Try())
  1722.         {
  1723.             if (gShowInvalidations && this->Focus())
  1724.                 FillRgn(((WindowPeek)fWMgrWindow)->updateRgn, qd.ltGray);
  1725.  
  1726.             this->DrawContents();
  1727.             fi.Success();
  1728.         }
  1729.         else                                    // Recover
  1730.             {
  1731.                 SetEmptyRgn(((WindowPeek)fWMgrWindow)->updateRgn);
  1732.  
  1733.                 // Or we get into an infinite loop 
  1734.                 // trying to update the window when 
  1735.                 // displaying an alert 
  1736.                 fUpdating = FALSE;
  1737.                 this->InvalidateFocus();
  1738.                 fi.ReSignal();
  1739.             }
  1740.  
  1741.         fUpdating = FALSE;
  1742.         
  1743.         // attempt to preserve the focus else blow it off
  1744. //        if (this->IsFocused())
  1745. //            {
  1746. //            VRect theExtent;
  1747. //            this->GetExtent(theExtent);
  1748. //            this->ValidateVRect(theExtent);
  1749. //            }
  1750. //        else
  1751.             {
  1752.             SetEmptyRgn(((WindowPeek)fWMgrWindow)->updateRgn);
  1753.             this->InvalidateFocus();
  1754.             }
  1755.     }
  1756. }
  1757.  
  1758. //--------------------------------------------------------------------------------------------------
  1759. #pragma segment MANonRes
  1760. //!!! Former nested routine, now a private method
  1761.  
  1762. pascal void TWindow::GetStandardStateFrame(const VRect& boundingRect,
  1763.                                             VRect& stdFrame)
  1764. {
  1765.     const short edge = 2;                        // leave space around window structure area, settable?
  1766.     VPoint delta;
  1767.     VRect localBoundingRect = boundingRect;
  1768.  
  1769.     localBoundingRect.Inset(VPoint(edge, edge));
  1770.  
  1771.     // calculate the maximum structure size 
  1772.     delta.h = Min((localBoundingRect.Length(hSel)), fResizeLimits[botRight][hSel] + fContDifference[hSel]);//!!! long-> short
  1773.     delta.v = Min((localBoundingRect.Length(vSel)), fResizeLimits[botRight][vSel] + fContDifference[vSel]);//!!! long-> short
  1774.  
  1775.     // Relocate the view only if necessary 
  1776.     if ((fLocation.v >= localBoundingRect.top) && ((fLocation.v + delta.v - fContDifference.v - 1) <= localBoundingRect.bottom))
  1777.         stdFrame.top = fLocation.v;
  1778.     else                                        // center in the screen 
  1779.         stdFrame.top = localBoundingRect.top + fContRgnInset.v + ((localBoundingRect.Length(vSel)) - delta.v) / 2;
  1780.  
  1781.     if ((fLocation.h >= localBoundingRect.left) && ((fLocation.h + delta.h - fContDifference.h - 1) <= localBoundingRect.right))
  1782.         stdFrame.left = fLocation.h;
  1783.     else                                        // center in the screen 
  1784.         stdFrame.left = localBoundingRect.left + fContRgnInset.h + ((localBoundingRect.Length(hSel)) - delta.h) / 2;
  1785.  
  1786.     stdFrame[botRight] = stdFrame[topLeft] + delta - VPoint(fContDifference) - VPoint(1, 1);
  1787. }
  1788.  
  1789. //--------------------------------------------------------------------------------------------------
  1790. #pragma segment MANonRes
  1791. //!!! Former nested routine, now a private method
  1792.  
  1793. pascal void TWindow::GetUserStateFrame(const VRect&    /* boundingRect */,
  1794.                                         VRect& userFrame)
  1795. {
  1796.     if ((fProcID) & zoomDocProc)            // check for a zoomable defproc 
  1797.         userFrame = (*((WStateDataHandle)(((WindowPeek)fWMgrWindow)->dataHandle)))->userState;
  1798.     else if (qDebug)
  1799.         ProgramBreak("Whoops");
  1800. }
  1801.  
  1802. //--------------------------------------------------------------------------------------------------
  1803. #pragma segment MANonRes
  1804.  
  1805. pascal void TWindow::Zoom(short partCode)
  1806. {
  1807.     Rect aGDScreenRect;
  1808.     VRect vr;
  1809.  
  1810.     // Find out where the window would like to be zoomed out to 
  1811.     this->GetMaxIntersectedDevice(aGDScreenRect);
  1812.     VRect aGDScreenVRect(aGDScreenRect);
  1813.  
  1814.     if (partCode == inZoomOut)
  1815.     {    // new zoom-out rect
  1816.         GetStandardStateFrame(aGDScreenVRect, vr);
  1817.         if ((fProcID) & zoomDocProc)        // check for a zoomable defproc 
  1818.             (*((WStateDataHandle)(((WindowPeek)fWMgrWindow)->dataHandle)))->stdState = vr;
  1819.     }
  1820.     else
  1821.     {    // new zoom-in rect
  1822.         GetUserStateFrame(aGDScreenVRect, vr);
  1823.         if ((fProcID) & zoomDocProc)    // check for a zoomable defproc 
  1824.             (*((WStateDataHandle)(((WindowPeek)fWMgrWindow)->dataHandle)))->userState = vr;
  1825.     }
  1826.  
  1827.     if (this->Focus())                            // The ROM requires that thePort be the window being zoomed.
  1828.     {
  1829.         Rect oldPortRect = qd.thePort->portRect;
  1830.  
  1831.         if (vr[topLeft] != fLocation)    // it moved 
  1832.             EraseRect(oldPortRect);
  1833.  
  1834.         if ((fProcID) & zoomDocProc)        // check for a zoomable defproc 
  1835.             ZoomWindow(fWMgrWindow, partCode, FALSE);
  1836.  
  1837.         // let the View know what we've done 
  1838.         if (vr[topLeft] == fLocation)
  1839.             // it didn't move: MacApp will handle invalidating, thank you
  1840.             this->ValidateRect(oldPortRect);
  1841.         else
  1842.             this->Locate(vr[topLeft], kDontInvalidate);
  1843.  
  1844.         this->Resize(VPoint(fWMgrWindow->portRect.Length(vSel), fWMgrWindow->portRect.Length(hSel)), kInvalidate);
  1845.     }
  1846. }
  1847.  
  1848. //--------------------------------------------------------------------------------------------------
  1849. #pragma segment MANonRes
  1850.  
  1851. pascal void TWindow::ZoomByUser(const VPoint& theMouse,
  1852.                                 short partCode)
  1853. {
  1854.     VPoint globalVMouse(theMouse);
  1855.  
  1856.     this->LocalToSuper(globalVMouse);
  1857.     if (TrackBox(fWMgrWindow, globalVMouse, partCode))
  1858.         this->Zoom(partCode);
  1859. }
  1860.  
  1861. //--------------------------------------------------------------------------------------------------
  1862. #pragma segment MAFields
  1863.  
  1864. pascal void TWindow::Fields(TObject* obj)        // override 
  1865. {
  1866.     obj->DoToField("TWindow", NULL, bClass);
  1867.     obj->DoToField("fWMgrWindow", &fWMgrWindow, bWindowPtr);
  1868.     obj->DoToField("fProcID", &fProcID, bInteger);
  1869.     obj->DoToField("fMoveBounds", &fMoveBounds, bRect);
  1870.     obj->DoToField("fResizeLimits", &fResizeLimits, bRect);
  1871.     obj->DoToField("fTarget", &fTarget, bObject);
  1872.     obj->DoToField("fTargetID", &fTargetID, bIDType);
  1873.     obj->DoToField("fPreDocName", &fPreDocname, bInteger);
  1874.     obj->DoToField("fConstTitle", &fConstTitle, bInteger);
  1875.     obj->DoToField("fMustAdapt", &fMustAdapt, bBoolean);
  1876.     obj->DoToField("fMustHorzCenter", &fMustHorzCenter, bBoolean);
  1877.     obj->DoToField("fMustVertCenter", &fMustVertCenter, bBoolean);
  1878.     obj->DoToField("fMustStagger", &fMustStagger, bBoolean);
  1879.     obj->DoToField("fMustForceOnScreen", &fMustForceOnScreen, bBoolean);
  1880.     obj->DoToField("fAdapted", &fAdapted, bBoolean);
  1881.     obj->DoToField("fHorzCentered", &fHorzCentered, bBoolean);
  1882.     obj->DoToField("fVertCentered", &fVertCentered, bBoolean);
  1883.     obj->DoToField("fStaggered", &fStaggered, bBoolean);
  1884.     obj->DoToField("fForcedOnScreen", &fForcedOnScreen, bBoolean);
  1885.     obj->DoToField("fIsActive", &fIsActive, bBoolean);
  1886.     obj->DoToField("fIsResizable", &fIsResizable, bBoolean);
  1887.     obj->DoToField("fIsClosable", &fIsClosable, bBoolean);
  1888.     obj->DoToField("fFreeOnClosing", &fFreeOnClosing, bBoolean);
  1889.     obj->DoToField("fDisposeOnFree", &fDisposeOnFree, bBoolean);
  1890.     obj->DoToField("fClosesDocument", &fClosesDocument, bBoolean);
  1891.     obj->DoToField("fOpenInitially", &fOpenInitially, bBoolean);
  1892.     obj->DoToField("fIsModal", &fIsModal, bBoolean);
  1893.     obj->DoToField("fDoFirstClick", &fDoFirstClick, bBoolean);
  1894.     obj->DoToField("fFloats", &fFloats, bBoolean);
  1895.     obj->DoToField("fDismissed", &fDismissed, bBoolean);
  1896.     obj->DoToField("fHideOnSuspend", &fHideOnSuspend, bBoolean);
  1897.     obj->DoToField("fWasHiddenOnSuspend", &fWasHiddenOnSuspend, bBoolean);
  1898.     obj->DoToField("fContRgnInset", &fContRgnInset, bPoint);
  1899.     obj->DoToField("fContDifference", &fContDifference, bPoint);
  1900.     obj->DoToField("fGenerateActivates", &fGenerateActivates, bBoolean);
  1901.  
  1902.     inherited::Fields(obj);
  1903. }
  1904.  
  1905. //--------------------------------------------------------------------------------------------------
  1906. #pragma segment MAWindowRes
  1907.  
  1908. Boolean IsDocumentWindow(WindowPtr aWindow)
  1909. // if a window is not a floater window and is not a system window then it is a document window 
  1910. {
  1911.     return ((!IsFloatWindow(aWindow)) && (!(((WindowPeek)(aWindow))->windowKind < 0)));
  1912. }
  1913.  
  1914. //--------------------------------------------------------------------------------------------------
  1915. #pragma segment MAWindowRes
  1916.  
  1917. pascal Boolean IsDialog(WindowPtr window)
  1918. {
  1919.     return ((((WindowPeek)window)->windowKind == dialogKind) && (GetWindowVariant(window) == dBoxProc));
  1920. }
  1921.  
  1922. //--------------------------------------------------------------------------------------------------
  1923.  
  1924. #pragma segment MAWindowRes
  1925.  
  1926. pascal Boolean IsGhostWindow(WindowPtr window)
  1927. {
  1928.     return (window == (WindowPtr)(*((LongIntPtr)GhostWindow)));
  1929. }
  1930.  
  1931. //--------------------------------------------------------------------------------------------------
  1932. #pragma segment MAWindowRes
  1933.  
  1934. pascal Boolean IsFloatWindow(WindowPtr window)
  1935. {
  1936.     return (((WindowPeek)window)->windowKind == kFloatWindowKind);
  1937. }
  1938.  
  1939. //--------------------------------------------------------------------------------------------------
  1940. #pragma segment MAWindowRes
  1941.  
  1942. // returns the last floating window in the window list
  1943. pascal WindowPtr GetLastFloatingWindowPtr(void)
  1944. {
  1945.     CWMgrIterator iter;
  1946.     WindowPtr lastFloatWindowPtr = NULL;
  1947.  
  1948.     for (WindowPtr aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  1949.     {
  1950.         if (IsFloatWindow(aWindowPtr))
  1951.             lastFloatWindowPtr = aWindowPtr;
  1952.         else if (!(((WindowPeek)aWindowPtr)->windowKind < 0))
  1953.             break;
  1954.     }
  1955.         
  1956.     return lastFloatWindowPtr;
  1957. }
  1958.  
  1959. //--------------------------------------------------------------------------------------------------
  1960. #pragma segment MAWindowRes
  1961.  
  1962. // returns the first hilited, visible, non-system document window in the window list.
  1963. // Ignores the ghost window (if any).
  1964. pascal WindowPtr MAGetActiveWindow(void)
  1965. {
  1966.     CWMgrIterator iter;
  1967.     
  1968.     for (WindowPtr aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  1969.         if ((((WindowPeek)aWindowPtr)->hilited) && (((WindowPeek)aWindowPtr)->visible)
  1970.                 && IsDocumentWindow(aWindowPtr) && !IsGhostWindow(aWindowPtr))
  1971.             return aWindowPtr;
  1972.     return NULL;
  1973. }
  1974.  
  1975. //--------------------------------------------------------------------------------------------------
  1976. #pragma segment MAWindowRes
  1977.  
  1978. // Returns the first visible, non-floater window in the window list. Ignores the ghost window (if any). 
  1979. pascal WindowPtr MAFrontWindow(void)
  1980. {
  1981.     CWMgrIterator iter;
  1982.  
  1983.     for (WindowPtr aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  1984.         if ((((WindowPeek)aWindowPtr)->visible) && !IsFloatWindow(aWindowPtr) && !IsGhostWindow(aWindowPtr))
  1985.             return aWindowPtr;
  1986.     return NULL;
  1987. }
  1988.  
  1989.